package p2p.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

import p2p.peer.client.Client;

public class Utils {

	public static UUID newUUID() {
		return UUID.randomUUID();
	}

	public static byte[] uuidToByteArray(UUID uuid) {

		long msb = uuid.getMostSignificantBits();
		long lsb = uuid.getLeastSignificantBits();
		byte[] buffer = new byte[16];

		for (int i = 0; i < 8; i++) {
			buffer[i] = (byte) (msb >>> 8 * (7 - i));
		}
		for (int i = 8; i < 16; i++) {
			buffer[i] = (byte) (lsb >>> 8 * (7 - i));
		}

		return buffer;

	}

	public static UUID toUUID(byte[] byteArray) {

		long msb = 0;
		long lsb = 0;
		for (int i = 0; i < 8; i++)
			msb = (msb << 8) | (byteArray[i] & 0xff);
		for (int i = 8; i < 16; i++)
			lsb = (lsb << 8) | (byteArray[i] & 0xff);
		UUID result = new UUID(msb, lsb);

		return result;
	}

	// Can not handle numbers > 1024
	@Deprecated
	public static byte[] intToArray(int num) {

		return new byte[] { (byte) ((num >> 24) & 0xFF),
				(byte) ((num >> 16) & 0xFF), (byte) ((num >> 8) & 0xFF),
				(byte) (num & 0xFF) };

	}

	// Can not handle numbers > 1024
	@Deprecated
	public static int arrayToInt(byte[] b) {
		return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16
				| (b[0] & 0xFF) << 24;
	}

	public static byte[] insertArray(byte[] res, byte[] arr, int pos) {

		int x = 0;

		for (int i = pos; i < arr.length; i++) {
			res[i] = arr[x];
			x++;
		}

		return res;
	}

	public static byte[] getSubArray(byte[] arr, int start, int end) {
		byte[] res = new byte[end - start];
		int j = 0;
		for (int i = start; i < end; i++) {
			res[j] = arr[i];
			j++;
		}
		return res;
	}

	public Set<Client> getClients(byte[] payload) {

		Set<Client> clients = new HashSet<Client>();

		byte[] tmp = new byte[4];

		for (int i = 0; i < payload.length; i = i + 4) {

			tmp = Utils.getSubArray(payload, i, i + 4);

			clients.add(new Client(tmp));

		}

		return clients;
	}

	// Transforms a byte array in to int number
	public static int byteArrayToInt(byte[] b) {
		return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16
				| (b[0] & 0xFF) << 24;
	}

	// Transforms a int into a byte array
	public static byte[] intToByteArray(int a) {
		return new byte[] { (byte) ((a >> 24) & 0xFF),
				(byte) ((a >> 16) & 0xFF), (byte) ((a >> 8) & 0xFF),
				(byte) (a & 0xFF) };
	}

	// Transforms a IP address into an array list , containing only the numbers
	public static byte[] getBytesFromIp(String ip) {
		byte[] list = new byte[4];

		InetAddress address;
		try {
			address = InetAddress.getByName(ip);
			list = address.getAddress();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return list;
	}

	// Transforms byte array into IP address
	public static String getIpFromBytesArray(byte[] arr) {
		String ip = "";
		for (byte i : arr) {
			ip += String.valueOf(i) + ".";
		}
		ip = ip.substring(0, ip.length() - 1);

		return ip;
	}

	// Transformation Methods
	public static byte[] ipToByteArray(String ip) {
		String[] arr = ip.split("\\.");
		byte[] res = new byte[4];
		int i = 0;

		for (String s : arr) {
			int n = Integer.parseInt(s);
			res[i] = (byte) (((byte) n) & 0xFF);
			i++;
		}

		return res;
	}

	public static String byteArrayToIp(byte[] iparr) {
		String res = "";

		for (byte s : iparr) {
			int t = s;
			res += String.valueOf(t & 0xFF) + ".";
		}

		return res.substring(0, res.length() - 1);
	}

}
